package com.hu.common.util.adm;

import com.hu.common.domain.dto.TreeDTO;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassName ListUtil
 * @Description 集合工具类
 * @author 355760
 **/
public class ListUtil {

    /**
     * 构建标签模板树
     *
     * @param list 标签模板集合
     * @param sort 是否需要根据sortNo排序
     * @return List<LabelTemplateTreeDTO>
     */
    public static List<? extends TreeDTO> buildTreeList(List<? extends TreeDTO> list, boolean sort) {
        if (list.size() > 0) {
            // 过滤出根节点
            List<? extends TreeDTO> rootList = list
                    .stream()
                    .filter(entity -> !entity.getIsLeaf())
                    .collect(Collectors.toList());
            sortByNo(sort, rootList);

            // 根据parentLabelId进行分组
            Map<Long, ? extends List<? extends TreeDTO>> map = list
                    .stream()
                    .filter(TreeDTO::getIsLeaf)
                    .collect(Collectors.groupingBy(TreeDTO::getParentId));

            // 递归构建节点
            recursionBuildTreeLeaf(rootList, map, sort);
            return rootList;
        }

        return null;
    }

    /**
     * 递归构建树形结构子节点
     *
     * @param rootList 根节点list
     * @param map      根据父节点分组list
     * @param sort     是否需要根据sortNo排序
     */
    private static void recursionBuildTreeLeaf(List<? extends TreeDTO> rootList,
                                               Map<Long, ? extends List<? extends TreeDTO>> map,
                                               boolean sort
    ) {
        rootList.forEach(entity -> {
            List<? extends TreeDTO> dtos = map.get(entity.getId());
            sortByNo(sort, dtos);
            entity.setChildren(dtos);
            if (Assert.notEmpty(dtos) && dtos.size() > 0) {
                recursionBuildTreeLeaf(dtos, map, sort);
            }
        });
    }

    /**
     * 根据sortNo排序
     * @param sort 是否需要排序
     * @param list 源数据
     */
    private static void sortByNo(boolean sort, List<? extends TreeDTO> list) {
        if (Assert.notEmpty(list) && list.size() > 0) {
            if (Assert.notEmpty(sort) && sort) {
                list.sort(Comparator.comparing(TreeDTO::getSortNo));
            }
        }
    }
}
